home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 4
/
The Arsenal Files 4 (Arsenal Computer).ISO
/
ham
/
sattrk31.tgz
/
sattrack-3.1.tar
/
SatTrack
/
src
/
xdemo
/
xdemo.c
Wrap
C/C++ Source or Header
|
1995-03-16
|
45KB
|
1,305 lines
/******************************************************************************/
/* */
/* Title : xdemo.c */
/* Author : Manfred Bester */
/* Date : 01Nov94 */
/* Last change : 15Mar95 */
/* */
/* Synopsis : SatTrack color world map demo program. */
/* */
/* */
/* SatTrack is Copyright (c) 1992, 1993, 1994, 1995 by Manfred Bester. */
/* All Rights Reserved. */
/* */
/* Permission to use, copy, and distribute SatTrack and its documentation */
/* in its entirety for educational, research and non-profit purposes, */
/* without fee, and without a written agreement is hereby granted, provided */
/* that the above copyright notice and the following three paragraphs appear */
/* in all copies. SatTrack may be modified for personal purposes, but */
/* modified versions may NOT be distributed without prior consent of the */
/* author. */
/* */
/* Permission to incorporate this software into commercial products may be */
/* obtained from the author, Dr. Manfred Bester, 1636 M. L. King Jr. Way, */
/* Berkeley, CA 94709, USA. Note that distributing SatTrack 'bundled' in */
/* with ANY product is considered to be a 'commercial purpose'. */
/* */
/* IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, */
/* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF */
/* THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR HAS BEEN ADVISED */
/* OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/* THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT */
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A */
/* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" */
/* BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, */
/* UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */
/* */
/******************************************************************************/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>
#include <X11/Xlib.h>
#include "satstrings.h"
#include "sattrack.h"
#include "mir.h"
#include "shuttle.h"
#include "world.xbm"
/******************************************************************************/
/* */
/* definitions */
/* */
/******************************************************************************/
#define MAPWIDTH (unsigned int) world_width /* [pixels] */
#define MAPHEIGHT (unsigned int) world_height /* [pixels] */
#define MAPTYPE (unsigned int) world_type /* 1 or 2 */
#define MAPWIDTHD (double) world_widthd /* [deg] */
#define MAPHEIGHTD (double) world_heightd /* [deg] */
#define GRIDSCALEX ((double) MAPWIDTH / MAPWIDTHD) /* [pixels/deg] */
#define GRIDSCALEY ((double) MAPHEIGHT / MAPHEIGHTD) /* [pixels/deg] */
#define MARGINTOP (unsigned int) 20
#define MARGINBOT (unsigned int) 20
#define MARGINLFT (unsigned int) 10
#define MARGINRGT (unsigned int) 10
#define WINWIDTH (unsigned int) (MAPWIDTH + MARGINLFT + MARGINRGT)
#define WINHEIGHT (unsigned int) (MAPHEIGHT + MARGINTOP + MARGINBOT)
#define HEADERROW (unsigned int) (MARGINTOP - 5)
#define FOOTERROW (unsigned int) (MARGINTOP + MAPHEIGHT + MARGINBOT - 5)
/******************************************************************************/
/* */
/* structures */
/* */
/******************************************************************************/
typedef struct {
double lng, lat;
} groundTrackType;
groundTrackType groundTrack[NSEGSGT];
/******************************************************************************/
/* */
/* X Window stuff and other global definitions */
/* */
/******************************************************************************/
Display *theDisplay;
Window theWindow;
GC theGC;
Colormap theColormap;
XColor color;
Drawable drawable;
Pixmap pixmap;
XSegment gridZero[2], gridLinesX[NGRIDX*2], gridLinesY[NGRIDY*2];
XSegment visibCircleSatPix[NSEGSVC], visibCircleGndPix[NSEGSVC];
XSegment visibCircleSunPix[NSEGSVC], groundTrackPix[NSEGSGT];
XPoint stsPoints[NSTSPOINTS], mirPoints[NMIRPOINTS];
Widget toplevel, frame;
XtAppContext appContext;
Arg warg[3];
double gndLtd, gndLng, satLtd, satLng, satHgt, sunLtd, sunLng, sunHgt,
ctyLtd, ctyLng, satLtdNew, satLngNew, satAzi, satEle,
satLngAdd, satLngFact, dLng, satLng0, phi, phiFact, inc,
separation, sepStep, sep, dh;
long timeInterval;
unsigned long numColors, foregroundPixel, backgroundPixel,
redPixel, greenPixel, lightGreenPixel,
nightBluePixel, darkBluePixel, oceanBluePixel,
lightBluePixel, veryLightBluePixel,
darkYellowPixel, lightYellowPixel,
blackPixel, darkGreyPixel, mediumGreyPixel, whitePixel;
unsigned int w, h;
int x, y, theScreen, secCount, secs, maxSecs, stsFlag, nPoints,
nFramePoints, nFramePointsTop, initFlag,
gndLocX, gndLocY, satLocX, satLocY, sunLocX, sunLocY,
ctyLocX, ctyLocY, satLocBakX, satLocBakY,
redrawFlag, daylightFlag, satTypeFlag, satSpot, verboseFlag;
char str[80], appName[80], gndName[80];
/******************************************************************************/
/* */
/* external functions */
/* */
/******************************************************************************/
extern double absol(), reduce();
extern void multMatVec();
extern void CalcGrid();
extern void CalcGroundTrack();
extern void CalcMapLocation();
extern void CalcVisibCircle();
extern void CleanSegments();
extern void CreateColors();
extern void DrawFrame();
extern void DrawMap();
extern void DrawMir();
extern void DrawSat();
extern void DrawShuttle();
extern void Quit();
extern void RedrawMap();
extern void ResizeMap();
extern void TimeLoop();
/******************************************************************************/
/* */
/* reduce: reduces number into specified interval (e.g. -PI, +PI) */
/* */
/******************************************************************************/
double reduce(value,rangeMin,rangeMax)
double value, rangeMin, rangeMax;
{
double range, rangeFrac, fullRanges, retval;
range = rangeMax - rangeMin;
rangeFrac = (rangeMax - value) / range;
modf(rangeFrac,&fullRanges);
retval = value + fullRanges * range;
if (retval > rangeMax)
retval -= range;
return(retval);
}
/******************************************************************************/
/* */
/* DrawShuttle: draws space shuttle */
/* */
/******************************************************************************/
void DrawShuttle()
{
int i;
nPoints = sizeof (stsPointsWhite) / sizeof (XPoint);
for (i = 0; i < nPoints; i++)
{
stsPoints[i].x = stsPointsWhite[i].x + (short int) satLocX;
stsPoints[i].y = stsPointsWhite[i].y + (short int) satLocY;
}
if (daylightFlag)
XSetForeground(theDisplay,theGC,whitePixel);
else
XSetForeground(theDisplay,theGC,mediumGreyPixel);
XDrawPoints(theDisplay,drawable,theGC,stsPoints,nPoints,CoordModeOrigin);
nPoints = sizeof (stsPointsBlack) / sizeof (XPoint);
for (i = 0; i < nPoints; i++)
{
stsPoints[i].x = stsPointsBlack[i].x + (short int) satLocX;
stsPoints[i].y = stsPointsBlack[i].y + (short int) satLocY;
}
XSetForeground(theDisplay,theGC,blackPixel);
XDrawPoints(theDisplay,drawable,theGC,stsPoints,nPoints,CoordModeOrigin);
return;
}
/******************************************************************************/
/* */
/* DrawMir: draws Mir space station */
/* */
/******************************************************************************/
void DrawMir()
{
int i;
nPoints = sizeof (mirPointsWhite) / sizeof (XPoint);
for (i = 0; i < nPoints; i++)
{
mirPoints[i].x = mirPointsWhite[i].x + (short int) satLocX;
mirPoints[i].y = mirPointsWhite[i].y + (short int) satLocY;
}
if (daylightFlag)
XSetForeground(theDisplay,theGC,whitePixel);
else
XSetForeground(theDisplay,theGC,mediumGreyPixel);
XDrawPoints(theDisplay,drawable,theGC,mirPoints,nPoints,CoordModeOrigin);
nPoints = sizeof (mirPointsBlack) / sizeof (XPoint);
for (i = 0; i < nPoints; i++)
{
mirPoints[i].x = mirPointsBlack[i].x + (short int) satLocX;
mirPoints[i].y = mirPointsBlack[i].y + (short int) satLocY;
}
XSetForeground(theDisplay,theGC,blackPixel);
XDrawPoints(theDisplay,drawable,theGC,mirPoints,nPoints,CoordModeOrigin);
return;
}
/******************************************************************************/
/* */
/* DrawSat: draws satellite */
/* */
/* selectFlag = TRUE color is blue (status = SELECT or MARK) */
/* = FALSE color is yellow */
/* */
/* dayFlag = TRUE color is light (blue or yellow) */
/* = FALSE color is dark (blue or yellow) */
/* */
/******************************************************************************/
void DrawSat(nStr,selectFlag,dayFlag)
int selectFlag, dayFlag;
char *nStr;
{
satSpot = (selectFlag) ? TRKSPOT : SATSPOT;
if (selectFlag && dayFlag)
XSetForeground(theDisplay,theGC,lightBluePixel);
if (selectFlag && !dayFlag)
XSetForeground(theDisplay,theGC,darkBluePixel);
if (!selectFlag && dayFlag)
XSetForeground(theDisplay,theGC,lightYellowPixel);
if (!selectFlag && !dayFlag)
XSetForeground(theDisplay,theGC,darkYellowPixel);
XFillRectangle(theDisplay,drawable,theGC,
satLocX - (int) satSpot ,satLocY - (int) satSpot,
(unsigned int) (satSpot*2+1),(unsigned int) (satSpot*2+1));
x = ((int) (MARGINLFT + MAPWIDTH) - satLocX > 100)
? 10 : -10 - ((int) (strlen(str)) * 6);
y = (satLocY - (int) MARGINTOP < 25) ? 20 : -8;
if (!dayFlag)
{
if (selectFlag)
XSetForeground(theDisplay,theGC,lightBluePixel);
else
XSetForeground(theDisplay,theGC,lightYellowPixel);
}
XDrawString(theDisplay,drawable,theGC,satLocX+x,satLocY+y,
nStr,(int) strlen(nStr));
return;
}
/******************************************************************************/
/* */
/* DrawFrame: draws the frame around world map and the text in the header and */
/* footer line */
/* */
/******************************************************************************/
void DrawFrame()
{
x = 0;
y = 0;
w = (unsigned int) (MARGINLFT + MAPWIDTH + MARGINRGT);
h = (unsigned int) MARGINTOP;
XSetForeground(theDisplay,theGC,blackPixel);
XFillRectangle(theDisplay,drawable,theGC,x,y,w,h);
XSetForeground(theDisplay,theGC,whitePixel);
sprintf(str,"STS-71");
XDrawString(theDisplay,drawable,theGC,(int) (MARGINLFT+2),
(int) HEADERROW,str,(int) strlen(str));
sprintf(str,"Orbit: 85");
XDrawString(theDisplay,drawable,theGC,(int) (MARGINLFT+0.17*MAPWIDTH),
(int) HEADERROW,str,(int) strlen(str));
/*
sprintf(str,"Azi: %3.0f",satAzi);
XDrawString(theDisplay,drawable,theGC,(int) (MARGINLFT+0.32*MAPWIDTH),
(int) HEADERROW,str,(int) strlen(str));
sprintf(str,"Ele: %3.0f",satEle);
XDrawString(theDisplay,drawable,theGC,(int) (MARGINLFT+0.42*MAPWIDTH),
(int) HEADERROW,str,(int) strlen(str));
*/
sprintf(str,"Lat: %2.0f %s",fabs(satLtd),(satLtd >= 0.0) ? "N" : "S");
XDrawString(theDisplay,drawable,theGC,(int) (MARGINLFT+0.38*MAPWIDTH),
(int) HEADERROW,str,(int) strlen(str));
sprintf(str,"Lng: %3.0f %s",fabs(satLng),(satLng >= 0.0) ? "W" : "E");
XDrawString(theDisplay,drawable,theGC,(int) (MARGINLFT+0.50*MAPWIDTH),
(int) HEADERROW,str,(int) strlen(str));
sprintf(str,"03Jun95 17:00:%02d UTC",secs);
XDrawString(theDisplay,drawable,theGC,(int) (MARGINLFT+0.70*MAPWIDTH),
(int) HEADERROW,str,(int) strlen(str));
x = 0;
y = (int) (MARGINTOP + MAPHEIGHT);
w = (unsigned int) (MARGINLFT + MAPWIDTH + MARGINRGT);
h = (unsigned int) MARGINBOT;
XSetForeground(theDisplay,theGC,blackPixel);
XFillRectangle(theDisplay,drawable,theGC,x,y,w,h);
XSetForeground(theDisplay,theGC,whitePixel);
sprintf(str,"Ground Track: ");
sprintf(str,"%s 96.0 km ESE of Hanga Roa, Easter Island (Chile)",str);
XDrawString(theDisplay,drawable,theGC,
(int) (MARGINLFT+2),(int) FOOTERROW,str,(int) strlen(str));
x = 0;
y = (int) MARGINTOP;
w = (unsigned int) MARGINLFT;
h = (unsigned int) MAPHEIGHT;
XSetForeground(theDisplay,theGC,blackPixel);
XFillRectangle(theDisplay,drawable,theGC,x,y,w,h);
x = (int) (MARGINLFT + MAPWIDTH);
y = (int) MARGINTOP;
w = (unsigned int) MARGINRGT;
h = (unsigned int) MAPHEIGHT;
XFillRectangle(theDisplay,drawable,theGC,x,y,w,h);
return;
}
/******************************************************************************/
/* */
/* DrawMap: draws window with world map and other features */
/* */
/******************************************************************************/
void DrawMap()
{
int i;
if (initFlag)
XClearWindow(theDisplay,drawable);
/* draw frame and header line */
DrawFrame();
/* draw world map */
if (initFlag)
pixmap = XCreateBitmapFromData(theDisplay,(Drawable) drawable,
(char *) world_bits,MAPWIDTH,MAPHEIGHT);
XSetForeground(theDisplay,theGC,foregroundPixel);
XSetBackground(theDisplay,theGC,backgroundPixel);
XCopyPlane(theDisplay,(Drawable) pixmap,(Drawable) drawable,theGC,0,0,
MAPWIDTH,MAPHEIGHT,(int) MARGINLFT,(int) MARGINTOP,1);
/* draw grid */
XSetForeground(theDisplay,theGC,mediumGreyPixel);
XDrawSegments(theDisplay,drawable,theGC,gridZero,2);
XSetForeground(theDisplay,theGC,darkGreyPixel);
XDrawSegments(theDisplay,drawable,theGC,gridLinesX,NGRIDX*2);
XDrawSegments(theDisplay,drawable,theGC,gridLinesY,NGRIDY*2);
/* draw Sun and terminator */
XSetForeground(theDisplay,theGC,lightYellowPixel);
XDrawSegments(theDisplay,drawable,theGC,visibCircleSunPix,NSEGSVC);
sprintf(str,"*");
XDrawString(theDisplay,drawable,theGC,sunLocX-2,sunLocY+5,
str,(int) strlen(str));
/* draw ground station */
XSetForeground(theDisplay,theGC,redPixel);
XDrawSegments(theDisplay,drawable,theGC,visibCircleGndPix,NSEGSVC);
XFillRectangle(theDisplay,drawable,theGC,
gndLocX - (int) GNDSPOT,gndLocY - (int) GNDSPOT,
(unsigned int) (GNDSPOT*2+1),(unsigned int) (GNDSPOT*2+1));
x = ((int) (MARGINLFT + MAPWIDTH) - gndLocX > 100)
? 10 : -10 - ((int) (strlen(str)) * 6);
y = (gndLocY - (int) MARGINTOP < 25) ? 20 : -8;
XSetForeground(theDisplay,theGC,veryLightBluePixel);
XDrawString(theDisplay,drawable,theGC,gndLocX+x,gndLocY+y,
gndName,(int) strlen(gndName));
/* draw nearest city */
CalcMapLocation(ctyLtd,ctyLng,&ctyLocX,&ctyLocY);
XSetForeground(theDisplay,theGC,redPixel);
XFillRectangle(theDisplay,drawable,theGC,
ctyLocX - (int) CTYSPOT,ctyLocY - (int) CTYSPOT,
(unsigned int) (CTYSPOT*2+1),(unsigned int) (CTYSPOT*2+1));
/* draw ground track */
XSetForeground(theDisplay,theGC,lightBluePixel);
XDrawSegments(theDisplay,drawable,theGC,groundTrackPix,NSEGSGT);
/* draw visibility circle */
XSetForeground(theDisplay,theGC,veryLightBluePixel);
XDrawSegments(theDisplay,drawable,theGC,visibCircleSatPix,NSEGSVC);
/* draw all satellites */
satTypeFlag = STS;
for (i = 0; i < 2; i++)
{
/*
CalcMapLocation(satLat*CRD,satLong*CRD,&satLocX,&satLocY);
*/
satTypeFlag = (satTypeFlag == MIR) ? STS : MIR;
switch(satTypeFlag)
{
case BASIC:
/*
strcpy(str,"%s",satName);
DrawSat(str,FALSE,TRUE);
*/
break;
case MIR:
CalcMapLocation(satLtd,satLng,&satLocX,&satLocY);
DrawMir();
break;
case STS:
satLngNew = satLng - separation;
satLngNew = reduce(satLngNew,-180.0,180.0);
satLtdNew = satLtd + separation;
satLocBakX = satLocX;
satLocBakY = satLocY;
CalcMapLocation(satLtdNew,satLngNew,&satLocX,&satLocY);
sep = reduce((satLng-satLngNew),0.0,360.0);
dh = satHgt - satHgt;
if ((sep < 5.0 || sep > 355.0) && fabs(dh) < 5.0)
{
satLocX = satLocBakX - 8; /* Mir-STS docking */
satLocY = satLocBakY + 16;
}
DrawShuttle();
break;
default:
break;
}
}
daylightFlag = (daylightFlag) ? FALSE : TRUE;
if (daylightFlag)
{
gndLtd = -7.3;
gndLng = -72.4;
sprintf(gndName,"%s","DGS");
}
else
{
gndLtd = 35.4;
gndLng = 116.9;
sprintf(gndName,"GDS");
gndLtd = 20.7;
gndLng = 156.3;
sprintf(gndName,"AMOS");
}
/* draw other satellites in multisat list */
strcpy(str,"HST");
CalcMapLocation(15.0,45.0,&satLocX,&satLocY);
DrawSat(str,FALSE,daylightFlag);
strcpy(str,"KO-23");
CalcMapLocation(-45.0,95.0,&satLocX,&satLocY);
DrawSat(str,TRUE,daylightFlag);
sprintf(str,"GRO");
CalcMapLocation(-10.0,75.0,&satLocX,&satLocY);
DrawSat(str,TRUE,daylightFlag);
sprintf(str,"UARS");
satLngNew = satLng + 90.0;
satLngNew = reduce(satLngNew,-180.0,180.0);
CalcMapLocation(satLtd,satLngNew,&satLocX,&satLocY);
DrawSat(str,FALSE,daylightFlag);
/* raise map */
if (initFlag)
XMapRaised(theDisplay,(Drawable) drawable);
initFlag = FALSE;
return;
}
/******************************************************************************/
/* */
/* RedrawMap: redraws map */
/* */
/******************************************************************************/
void RedrawMap()
{
if (redrawFlag)
{
if (verboseFlag)
printf("redrawing map ...\n");
CalcGroundTrack();
CalcMapLocation(gndLtd,gndLng,&gndLocX,&gndLocY);
CalcMapLocation(satLtd,satLng,&satLocX,&satLocY);
CalcMapLocation(sunLtd,sunLng,&sunLocX,&sunLocY);
CalcVisibCircle(&visibCircleGndPix[0],gndLtd,gndLng,satHgt);
CalcVisibCircle(&visibCircleSatPix[0],satLtd,satLng,satHgt);
CalcVisibCircle(&visibCircleSunPix[0],sunLtd,sunLng,sunHgt);
DrawMap();
redrawFlag = FALSE;
}
return;
}
/******************************************************************************/
/* */
/* ResizeMap: resizes map */
/* */
/******************************************************************************/
void ResizeMap()
{
if (verboseFlag)
printf("--> this doesn't work yet!\n");
return;
}
/******************************************************************************/
/* */
/* TimeLoop: performs cyclic update of satellite position */
/* */
/******************************************************************************/
void TimeLoop(i,id)
int i;
XtIntervalId *id;
{
secCount += (int) (timeInterval / 1000);
sunLng += (double) timeInterval / 1000.0 / 86400.0 * 360;
sunLng = reduce(sunLng,-180.0,180.0);
if (secCount > maxSecs)
secCount = 0;
secs = secCount % 60;
dLng = satLngFact * fabs(satLngAdd);
satLtd = -inc * sin((dLng * (double) secCount) * CDR) + ONEPPM;
phi = -phiFact * (double) secCount * satLngAdd / 3.0 / 360.0;
satLng = reduce(satLng0 + ((double) secCount) * dLng + phi,-180.0,180.0);
if (separation < -22.5)
{
separation = -22.5;
sepStep = 0.5;
}
if (separation > 0.0)
{
separation = 0.0;
sepStep = -0.5;
}
separation += sepStep;
CalcGroundTrack();
CalcMapLocation(gndLtd,gndLng,&gndLocX,&gndLocY);
CalcMapLocation(satLtd,satLng,&satLocX,&satLocY);
CalcMapLocation(sunLtd,sunLng,&sunLocX,&sunLocY);
CalcVisibCircle(&visibCircleGndPix[0],gndLtd,gndLng,satHgt);
CalcVisibCircle(&visibCircleSatPix[0],satLtd,satLng,satHgt);
CalcVisibCircle(&visibCircleSunPix[0],sunLtd,sunLng,sunHgt);
redrawFlag = TRUE;
DrawMap();
timeInterval = 2000L;
XtAppAddTimeOut(appContext,timeInterval,TimeLoop,0);
return;
}
/******************************************************************************/
/* */
/* QuitMain: quits main program */
/* */
/******************************************************************************/
void Quit()
{
if (verboseFlag)
printf("closing window ...\n");
XFreePixmap(theDisplay,pixmap);
XFreeGC(theDisplay,theGC);
XDestroyWindow(theDisplay,XtWindow(toplevel));
XCloseDisplay(theDisplay);
if (verboseFlag)
printf("\ndid you have a good time watching this?\n\n");
exit(-1);
}
/******************************************************************************/
/* */
/* CreateColors: creates all colors needed */
/* */
/******************************************************************************/
void CreateColors()
{
theColormap = DefaultColormap(theDisplay,theScreen);
color.flags = DoRed | DoGreen | DoBlue;
color.red = (unsigned short) 65535; /* red */
color.green = (unsigned short) 20000;
color.blue = (unsigned short) 25000;
XAllocColor(theDisplay,theColormap,&color);
redPixel = color.pixel;
color.red = (unsigned short) 18000; /* green */
color.green = (unsigned short) 48000;
color.blue = (unsigned short) 2000;
XAllocColor(theDisplay,theColormap,&color);
greenPixel = color.pixel;
color.red = (unsigned short) 18000; /* light green */
color.green = (unsigned short) 52000;
color.blue = (unsigned short) 2000;
XAllocColor(theDisplay,theColormap,&color);
lightGreenPixel = color.pixel;
color.red = (unsigned short) 5000; /* night blue */
color.green = (unsigned short) 5000;
color.blue = (unsigned short) 35000;
XAllocColor(theDisplay,theColormap,&color);
nightBluePixel = color.pixel;
color.red = (unsigned short) 34000; /* dark blue */
color.green = (unsigned short) 34000;
color.blue = (unsigned short) 52000;
XAllocColor(theDisplay,theColormap,&color);
darkBluePixel = color.pixel;
color.red = (unsigned short) 12500; /* ocean blue */
color.green = (unsigned short) 7500;
color.blue = (unsigned short) 50000;
XAllocColor(theDisplay,theColormap,&color);
oceanBluePixel = color.pixel;
color.red = (unsigned short) 40000; /* light blue */
color.green = (unsigned short) 60000;
color.blue = (unsigned short) 65535;
XAllocColor(theDisplay,theColormap,&color);
lightBluePixel = color.pixel;
color.red = (unsigned short) 62000; /* very light blue */
color.green = (unsigned short) 65535;
color.blue = (unsigned short) 65535;
XAllocColor(theDisplay,theColormap,&color);
veryLightBluePixel = color.pixel;
color.red = (unsigned short) 52000; /* dark yellow */
color.green = (unsigned short) 52000;
color.blue = (unsigned short) 34000;
XAllocColor(theDisplay,theColormap,&color);
darkYellowPixel = color.pixel;
color.red = (unsigned short) 65535; /* light yellow */
color.green = (unsigned short) 65535;
color.blue = (unsigned short) 35000;
XAllocColor(theDisplay,theColormap,&color);
lightYellowPixel = color.pixel;
color.red = (unsigned short) 0; /* black */
color.green = (unsigned short) 0;
color.blue = (unsigned short) 0;
XAllocColor(theDisplay,theColormap,&color);
blackPixel = color.pixel;
color.red = (unsigned short) 40000; /* dark grey */
color.green = (unsigned short) 40000;
color.blue = (unsigned short) 45000;
XAllocColor(theDisplay,theColormap,&color);
darkGreyPixel = color.pixel;
color.red = (unsigned short) 48000; /* medium grey */
color.green = (unsigned short) 48000;
color.blue = (unsigned short) 52000;
XAllocColor(theDisplay,theColormap,&color);
mediumGreyPixel = color.pixel;
color.red = (unsigned short) 65535; /* white */
color.green = (unsigned short) 65535;
color.blue = (unsigned short) 65535;
XAllocColor(theDisplay,theColormap,&color);
whitePixel = color.pixel;
return;
}
/******************************************************************************/
/* */
/* CalcGrid: calculates grid */
/* */
/******************************************************************************/
void CalcGrid()
{
double gridStepX, gridStepY;
int i, j, mapCenterX, mapCenterY;
mapCenterX = (int) (MARGINLFT + MAPWIDTH / 2 - 1);
mapCenterY = (int) (MARGINTOP + MAPHEIGHT / 2 - 1);
gridZero[0].x1 = mapCenterX; /* zero meridian */
gridZero[0].x2 = mapCenterX;
gridZero[0].y1 = (int) MARGINTOP;
gridZero[0].y2 = (int) (MARGINTOP + MAPHEIGHT - 1);
gridZero[1].x1 = (int) MARGINLFT; /* equator */
gridZero[1].x2 = (int) (MARGINLFT + MAPWIDTH - 1);
gridZero[1].y1 = mapCenterY;
gridZero[1].y2 = mapCenterY;
gridStepX = GRIDSTEPX * GRIDSCALEX;
gridStepY = GRIDSTEPY * GRIDSCALEY;
for (i = 0; i < NGRIDX; i++) /* vertical */
{
j = 2 * i;
gridLinesX[j].x1 = mapCenterX + (int) ((double) (i+1) * gridStepX);
gridLinesX[j].x2 = mapCenterX + (int) ((double) (i+1) * gridStepX);
gridLinesX[j+1].x1 = mapCenterX - (int) ((double) (i+1) * gridStepX);
gridLinesX[j+1].x2 = mapCenterX - (int) ((double) (i+1) * gridStepX);
gridLinesX[j].y1 = (int) MARGINTOP;
gridLinesX[j].y2 = (int) (MARGINTOP + MAPHEIGHT - 1);
gridLinesX[j+1].y1 = (int) MARGINTOP;
gridLinesX[j+1].y2 = (int) (MARGINTOP + MAPHEIGHT - 1);
}
for (i = 0; i < NGRIDY; i++) /* horizontal */
{
j = 2 * i;
gridLinesY[j].x1 = (int) MARGINLFT;
gridLinesY[j].x2 = (int) (MARGINLFT + MAPWIDTH - 1);
gridLinesY[j+1].x1 = (int) MARGINLFT;
gridLinesY[j+1].x2 = (int) (MARGINLFT + MAPWIDTH - 1);
gridLinesY[j].y1 = mapCenterY + (int) ((double) (i+1) * gridStepY);
gridLinesY[j].y2 = mapCenterY + (int) ((double) (i+1) * gridStepY);
gridLinesY[j+1].y1 = mapCenterY - (int) ((double) (i+1) * gridStepY);
gridLinesY[j+1].y2 = mapCenterY - (int) ((double) (i+1) * gridStepY);
}
return;
}
/******************************************************************************/
/* */
/* CalcMapLocation: calculates location of ground station, satellite and Sun */
/* */
/******************************************************************************/
void CalcMapLocation(mapLtd,mapLng,mapX,mapY)
double mapLtd, mapLng;
int *mapX, *mapY;
{
*mapX = (int) ((MAPWIDTHD / 2.0 - mapLng) * GRIDSCALEX);
*mapY = (int) ((MAPHEIGHTD / 2.0 - mapLtd) * GRIDSCALEY);
*mapX += (int) MARGINLFT - 1;
*mapY += (int) MARGINTOP - 1;
return;
}
/******************************************************************************/
/* */
/* CalcVisibCircle: calculates circle of visibility around sub-satellite */
/* point, using an Euler matrix for the vector rotation */
/* */
/******************************************************************************/
void CalcVisibCircle(visibCirclePix,circLtd,circLng,circHgt)
XSegment *visibCirclePix;
double circLtd, circLng, circHgt;
{
double descMat[3][3], u[3], q[3];
double arg, circStep, qabs;
double theta, psi, gamma, beta, lambda, lat, lng;
double cosTheta, sinTheta, cosPsi, sinPsi;
double cosBeta, sinBeta, cosLambda, sinLambda;
int i, k, posX, posY;
theta = HALFPI - circLtd*CDR;
psi = HALFPI - circLng*CDR;
cosTheta = cos(theta);
sinTheta = sin(theta);
cosPsi = cos(psi);
sinPsi = sin(psi);
descMat[0][0] = sinPsi*cosTheta;
descMat[0][1] = -cosPsi;
descMat[0][2] = sinPsi*sinTheta;
descMat[1][0] = cosPsi*cosTheta;
descMat[1][1] = sinPsi;
descMat[1][2] = cosPsi*sinTheta;
descMat[2][0] = -sinTheta;
descMat[2][1] = 0.0;
descMat[2][2] = cosTheta;
arg = EARTHRADIUS / (EARTHRADIUS + circHgt);
if (arg > 1.0) arg = 1.0;
if (arg < -1.0) arg = -1.0;
gamma = acos(arg);
beta = HALFPI - gamma;
cosBeta = cos(beta);
sinBeta = sin(beta);
circStep = 360.0 / ((double) NSEGSVC);
for (k = 0; k < NSEGSVC; k++)
{
lambda = (double) (circStep * k) * CDR;
cosLambda = cos(lambda);
sinLambda = sin(lambda);
u[0] = cosLambda*cosBeta;
u[1] = sinLambda*cosBeta;
u[2] = sinBeta;
multMatVec(u,q,descMat);
qabs = absol(q);
for (i = 0; i <= 2; i++)
q[i] /= qabs;
arg = q[2];
if (arg > 1.0) arg = 1.0;
if (arg < -1.0) arg = -1.0;
lat = asin(arg) * CRD;
q[2] = 0.0;
qabs = absol(q);
q[0] /= qabs;
q[1] /= qabs;
lng = atan2(q[1],q[0]) * CRD;
lng = reduce(lng,-MAPWIDTHD/2.0,MAPWIDTHD/2.0);
posX = (int) ((MAPWIDTHD / 2.0 - lng) * GRIDSCALEX + MARGINLFT - 0.5);
posY = (int) ((MAPHEIGHTD / 2.0 - lat) * GRIDSCALEY + MARGINTOP - 0.5);
visibCirclePix[k].x1 = (short int) posX;
visibCirclePix[k].y1 = (short int) posY;
if (k > 0)
{
visibCirclePix[k-1].x2 = visibCirclePix[k].x1;
visibCirclePix[k-1].y2 = visibCirclePix[k].y1;
}
}
visibCirclePix[NSEGSVC-1].x2 = visibCirclePix[0].x1; /* close circle */
visibCirclePix[NSEGSVC-1].y2 = visibCirclePix[0].y1;
CleanSegments(&visibCirclePix[0],NSEGSVC,TRUE);
return;
}
/******************************************************************************/
/* */
/* CalcGroundTrack: calculates ground track */
/* */
/******************************************************************************/
void CalcGroundTrack()
{
int k, gndX, gndY;
dLng = satLngFact * (MAPWIDTHD / (double) NSEGS);
for (k = 0; k < NSEGSGT; k++)
{
phi = -phiFact * (double) k / (double) NSEGSGT;
groundTrack[k].lng = reduce(satLng0+(double) k * dLng+phi,-180.0,180.0);
groundTrack[k].lat = -inc * sin((dLng * (double) k) * CDR) + ONEPPM;
}
for (k = 0; k < NSEGSGT; k++)
{
gndX = (int) ((MAPWIDTHD/2.0 - groundTrack[k].lng) * GRIDSCALEX +
MARGINLFT - 0.5);
gndY = (int) ((MAPHEIGHTD/2.0 - groundTrack[k].lat) * GRIDSCALEY +
MARGINTOP - 0.5);
groundTrackPix[k].x1 = (short int) gndX;
groundTrackPix[k].y1 = (short int) gndY;
if (k > 0)
{
groundTrackPix[k-1].x2 = groundTrackPix[k].x1;
groundTrackPix[k-1].y2 = groundTrackPix[k].y1;
}
}
groundTrackPix[NSEGSGT-1].x2 = groundTrackPix[NSEGSGT-1].x1;
groundTrackPix[NSEGSGT-1].y2 = groundTrackPix[NSEGSGT-1].y1;
CleanSegments(&groundTrackPix[0],NSEGSGT,FALSE);
return;
}
/******************************************************************************/
/* */
/* CleanSegments: cleans up line segments (wrap around at map boundaries) */
/* */
/******************************************************************************/
void CleanSegments(xSegments,numSegments,visibCircleFlag)
XSegment *xSegments;
int numSegments, visibCircleFlag;
{
int k, k0, n, dx, dy, dX, dY;
k0 = (visibCircleFlag) ? 0 : -1;
for (k = 0; k < numSegments + k0; k++)
{
n = (visibCircleFlag && k == numSegments - 1) ? 0 : k+1;
if (xSegments[k].x1 - xSegments[k].x2 > (short int) (MAPWIDTH / 2))
{
dx = (int) (MAPWIDTH + MARGINLFT) - (int) xSegments[k].x1;
dX = (int) xSegments[k].x2 - (int) MARGINLFT + dx;
dY = (int) (xSegments[k].y2 - xSegments[k].y1);
dy = (int) ((double) dY / (double) dX * (double) dx);
xSegments[n].x1 = xSegments[k].x2 - (short int) (dX - dx);
xSegments[k].x2 = xSegments[k].x1 + (short int) (dx - 1);
xSegments[n].y1 = xSegments[k].y2 - (short int) (dY - dy);
xSegments[k].y2 = xSegments[k].y1 + (short int) dy;
}
if (xSegments[k].x2 - xSegments[k].x1 > (short int) (MAPWIDTH / 2))
{
dx = (int) xSegments[k].x1 - (int) MARGINLFT;
dX = (int) (MAPWIDTH + MARGINLFT) - (int) xSegments[k].x2 + dx;
dY = (int) (xSegments[k].y2 - xSegments[k].y1);
dy = (int) ((double) dY / (double) dX * (double) dx);
xSegments[n].x1 = xSegments[k].x2 + (short int) (dX - dx);
xSegments[k].x2 = xSegments[k].x1 - (short int) (dx - 1);
xSegments[n].y1 = xSegments[k].y2 - (short int) (dY - dy);
xSegments[k].y2 = xSegments[k].y1 + (short int) dy;
}
}
for (k = 0; k < numSegments; k++)
{
if (xSegments[k].y1 < (short int) MARGINTOP)
xSegments[k].y1 = (short int) MARGINTOP;
if (xSegments[k].y2 < (short int) MARGINTOP)
xSegments[k].y2 = (short int) MARGINTOP;
if (xSegments[k].y1 > (short int) (MAPHEIGHT + MARGINTOP - 1))
xSegments[k].y1 = (short int) (MAPHEIGHT + MARGINTOP - 1);
if (xSegments[k].y2 > (short int) (MAPHEIGHT + MARGINTOP - 1))
xSegments[k].y2 = (short int) (MAPHEIGHT + MARGINTOP - 1);
}
return;
}
/******************************************************************************/
/* */
/* main program */
/* */
/******************************************************************************/
void main(argc,argv)
int argc;
char *argv[];
{
int n;
initFlag = TRUE;
if (argc > 1)
verboseFlag = (!strcmp(argv[1],"-v")) ? TRUE : FALSE;
sprintf(appName,"%s %s Graphics Demo Program",sattrName,sattrVersion);
if (verboseFlag)
printf("\ninitializing toolkit for 'xdemo' ...\n");
XtToolkitInitialize();
appContext = XtCreateApplicationContext();
theDisplay = XtOpenDisplay(appContext,NULL,appName,appName,NULL,0,
&argc,argv);
if (!theDisplay)
{
printf("Error: cannot open display.\n");
exit(-1);
}
theScreen = DefaultScreen(theDisplay);
numColors = XDisplayCells(theDisplay,theScreen);
if (verboseFlag)
printf("creating toplevel and frame ...\n");
toplevel = XtAppCreateShell(appName,appName,
applicationShellWidgetClass,theDisplay,NULL,0);
if (verboseFlag)
printf("creating colors ...\n");
CreateColors();
if (MAPTYPE == 1) /* fill map */
{
foregroundPixel = greenPixel;
backgroundPixel = oceanBluePixel;
}
else /* line map */
{
foregroundPixel = lightGreenPixel;
backgroundPixel = nightBluePixel;
}
if (verboseFlag)
printf("map size: %dx%d pixels, %.0fx%.0f deg\n",
MAPWIDTH,MAPHEIGHT,MAPWIDTHD,MAPHEIGHTD);
n = 0;
XtSetArg(warg[n],XtNwidth,WINWIDTH); n++;
XtSetArg(warg[n],XtNheight,WINHEIGHT); n++;
XtSetArg(warg[n],XtNbackground,blackPixel); n++;
frame = XtCreateManagedWidget("frame",widgetClass,toplevel,warg,n);
/* data */
secCount = 0;
gndLtd = -7.3; /* Diego Garcia */
gndLng = -72.4;
sprintf(gndName,"%s","DGS");
sunLtd = -15.0; /* Sun position */
sunLng = 20.0;
sunHgt = EARTHSMA;
ctyLtd = -27.0; /* Easter Island */
ctyLng = 109.0;
satLng0 = 147.5; /* ground track data */
satLngAdd = 1.0;
satLngFact = -1.0;
inc = 51.0;
phiFact = 67.5;
separation = -22.0; /* initial separation STS - Mir */
sepStep = 0.5;
satLtd = 0.0; /* initial satellite position */
satLng = satLng0;
satHgt = 410.0;
maxSecs = (int) (3.0 * 360.0 / satLngAdd + ONEPPM);
if (verboseFlag)
printf("calculating grid and ground station ...\n");
CalcGrid();
if (verboseFlag)
printf("calculating ground track ...\n");
CalcGroundTrack();
CalcMapLocation(gndLtd,gndLng,&gndLocX,&gndLocY);
CalcMapLocation(satLtd,satLng,&satLocX,&satLocY);
CalcMapLocation(sunLtd,sunLng,&sunLocX,&sunLocY);
if (verboseFlag)
printf("calculating visibility circles ...\n");
CalcVisibCircle(&visibCircleGndPix[0],gndLtd,gndLng,satHgt);
CalcVisibCircle(&visibCircleSatPix[0],satLtd,satLng,satHgt);
CalcVisibCircle(&visibCircleSunPix[0],sunLtd,sunLng,sunHgt);
if (verboseFlag)
printf("realizing top level ...\n");
XtRealizeWidget(toplevel);
if (verboseFlag)
printf("creating graphics context ...\n");
theWindow = XtWindow(toplevel);
theGC = XCreateGC(theDisplay,theWindow,0,0);
drawable = XtWindow(frame);
if (verboseFlag)
printf("programming event handlers ...\n");
redrawFlag = TRUE;
daylightFlag = TRUE;
XtAddEventHandler(frame,ButtonPressMask,FALSE,Quit,NULL);
XtAddEventHandler(frame,StructureNotifyMask,FALSE,ResizeMap,NULL);
XtAddEventHandler(frame,ExposureMask,FALSE,RedrawMap,NULL);
XMapRaised(theDisplay,(Drawable) drawable);
if (verboseFlag)
printf("starting timer ...\n");
timeInterval = 100L;
XtAppAddTimeOut(appContext,timeInterval,TimeLoop,0);
if (verboseFlag)
{
printf("entering application main loop ...\n");
printf("\n");
printf("to quit hit mouse button while cursor is inside graphics ");
printf("window\n");
printf("\n");
}
XtAppMainLoop(appContext);
}
/******************************************************************************/
/* */
/* End of program xdemo.c */
/* */
/******************************************************************************/